package com.m1.tzolkin.model.util;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Stock<E extends IResource> implements IStock<E> {

	// ATTRIBUTS
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -252017361128206450L;
	private final Map<E, Integer> value;
	
	// CONSTRUCTEUR
	
	public Stock() {
		value = new HashMap<E, Integer>();
	}
	
	public Stock(IStock<E> s) {
		this();
		if (s == null) {
			throw new IllegalArgumentException();
		}
		add(s);
	}
	
	// REQUETES

	@Override
	public int get(E r) {
		if (r == null) {
			throw new IllegalArgumentException();
		}
		return value.get(r) == null ? 0 : value.get(r);
	}
	
	@Override
	public boolean contains(IStock<E> m) {
		if (m == null) {
			throw new IllegalArgumentException();
		}
		for (E e : m.keySet()) {
			if (get(e) < m.get(e)) {
				return false;
			}
		}
		return true;
	}
	
	@Override
	public boolean contains(IStock<E> m, E r) {
		if (m == null || r == null) {
			throw new IllegalArgumentException();
		}
		for (E e : m.keySet()) {
			if (e.equals(r)) {
				if (m.get(e) - get(e) > 1) {
					return false;
				}
			} else {
				if (m.get(e) - get(e) > 0) {
					return false;
				}
			}
		}
		return true;
	}

	@Override
	public Set<E> keySet() {
		return value.keySet();
	}

	@Override
	public boolean equals(IStock<E> s) {
		if (s == null) {
			return false;
		}
		return s.contains(this) && this.contains(s);
	}
	
	@Override
	public int getTotal() {
		int total = 0;
		for (E e : keySet()) {
			total += get(e);
		}
		return total;
	}
	
	// COMMANDES

	@Override
	public IStock<E> add(E e) {
		return add(e, 1);
	}

	@Override
	public IStock<E> remove(E e) {
		return remove(e, 1);
	}

	@Override
	public IStock<E> add(E e, int i) {
		if (e == null || i < 0) {
			throw new IllegalArgumentException();
		}
		value.put(e, get(e) + i);
		return this;
	}

	@Override
	public IStock<E> remove(E e, int i) {
		if (e == null || i < 0) {
			throw new IllegalArgumentException();
		}
		value.put(e, get(e) - i);
		return this;
	}

	@Override
	public IStock<E> add(IStock<E> s) {
		if (s == null) {
			throw new IllegalArgumentException();
		}
		int n;
		for (E e : s.keySet()) {
			n = s.get(e);
			if (n > 1) {
				add(e, n);
			}
		}
		return this;
	}

	@Override
	public IStock<E> remove(IStock<E> s) {
		if (s == null) {
			throw new IllegalArgumentException();
		}
		int n;
		for (E e : s.keySet()) {
			n = s.get(e);
			if (n > 1) {
				remove(e, n);
			}
		}
		return this;
	}
	
}
